package com.xiyuan.smartutils.xml.parser;

import com.xiyuan.SysI18n;
import com.xiyuan.smartutils.*;
import com.xiyuan.smartutils.xml.Xml;
import com.xiyuan.smartutils.xml.XmlParser;
import com.xiyuan.smartutils.xml.XmlTag;
import com.xiyuan.smartutils.xml.Xmls;
import org.w3c.dom.Node;

import java.lang.reflect.Field;
import java.util.List;

/**
 * 对象适配器，不包括基本类型、数组类型
 *
 * @version v1.1.2 @author lgz 2017-8-21 新建与整理
 */
public class ObjectParser implements XmlParser {
    private Xml xmlMain;
    
    @Override
    public XmlParser set(Xml xmlMain) {
        this.xmlMain = xmlMain;
        return this;
    }
    
    @Override
    public String toStringInner(Object obj, String tagName, int tagLevel) {// 类对象，以自己的标记为准，不采用字段的标记
        
        Class<?> clazz = obj.getClass();
        if (tagName == null && (obj instanceof XmlTag)) {tagName = ((XmlTag) obj).getXmlTag();}
        
        if (tagName == null) {tagName = Xmls.getXmlClassTag(clazz);}
        
        Asserts.as(Validates.isNotBlank(tagName) ? null : "对象转XML时未定义XmlClassTag");
        
        StringBuilder strb = new StringBuilder();
        StrUtils.addNewLine(strb);
        StrUtils.addTwoSpace(strb, tagLevel);
        Xmls.addTagBegin(strb, tagName);
        
        List<Field> fieldList = Classes.getFields(clazz, true);
        for (Field field : fieldList) {
            String name = Annotations.getFieldName(field);
            Object value = Classes.getFieldValue(obj, field);
            if (value == null) {
                continue;// 为null不传入
            }
            
            boolean hasGroup = Xmls.hasXmlFieldGroup(field);
            strb.append(xmlMain.toStringInner(value, hasGroup ? name : null, hasGroup ? tagLevel + 1 : tagLevel));
        }
        
        StrUtils.addNewLine(strb);
        StrUtils.addTwoSpace(strb, tagLevel);
        Xmls.addTagEnd(strb, tagName);
        return strb.toString();
    }
    
    @Override
    public Object toObjectInner(Node node, Class<?> cls, Class<?> generics) {
        String tag = Xmls.getXmlClassTag(cls);
        if (!Xmls.isOwn(node, tag)) {return null;}
        
        Object obj = Classes.newInstance(cls);
        Asserts.nonNull(obj, SysI18n.classDoesNotSupportNoParameterConstructors);
        
        List<Field> fieldList = Classes.getFields(cls, true);
        for (Field field : fieldList) {
            Class<?> fieldClass = field.getType();
            String fieldName = Annotations.getFieldName(field);
            Class<?> fieldGenerics = Annotations.getGenericsClass(field);
            
            // 判断是否有组号，如果有则取组号下内容，默认都有组号，没有则还是在node下
            Node fieldNode = Xmls.hasXmlFieldGroup(field) ? Xmls.getNode(node, fieldName) : node;
            Object value = xmlMain.toObjectInner(fieldNode, fieldClass, fieldGenerics);
            Classes.setFieldValue(obj, field, value);
        }
        
        return obj;
    }
}
